import { Inject, Injectable } from '@nestjs/common';
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
import { PaginationDto } from 'src/common/dto/pagination.dto';
import { ToolsService } from 'src/utils/tools.service';
import { DataSource, Repository } from 'typeorm';
import { UsersEntity } from '../user/entities/user.entity';
import { CreateTagDto } from './dto/create-tag.dto';
import { UpdateTagDto } from './dto/update-tag.dto';
import { TagEntity } from './entities/tag.entity';
import { v4 as uuidv4 } from 'uuid';
import * as moment from 'moment';
import { Cache } from 'cache-manager';
import { CACHE_MANAGER } from '@nestjs/cache-manager';

@Injectable()
export class TagService {
  @InjectRepository(TagEntity)
  private readonly tagsRepository: Repository<TagEntity>;

  @InjectDataSource()
  private readonly dataSource: DataSource;

  constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}

  async create(createTagDto: CreateTagDto, userid: string) {
    const queryRunner = this.dataSource.createQueryRunner();
    try {
      // 清除整个缓存
      await this.cacheManager.reset();
      const manager = await queryRunner.manager; //使用事务
      const user = await manager
        .getRepository(UsersEntity)
        .createQueryBuilder('user')
        .where('user.id = :id', {
          id: userid,
        })
        .getOne();
      if (!user) {
        throw new Error('用户不存在');
      }
      const tag = new TagEntity();
      tag.tagname = createTagDto.tagname;
      tag.sortOrder = createTagDto.sortOrder || 0;
      tag.user = user;
      await manager.save(tag);
      return user;
    } catch (error) {
      ToolsService.fail(error);
    } finally {
      await queryRunner.release();
    }
  }

  async createUseNativeSql(createTagDto: CreateTagDto) {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect(); //使用我们的新queryRunner建立真正的数据库连
    await queryRunner.startTransaction();
    try {
      // 清除整个缓存
      await this.cacheManager.reset();
      let id = uuidv4();
      let created_at = moment().format('YYYY-MM-DD HH:mm:ss');
      let query = `INSERT INTO tag (id,tagname,created_at) VALUES ('${id}' ,'${createTagDto.tagname}','${created_at}')`;
      console.log('query', query);
      // 执行原生SQL
      await queryRunner.query(query);
      // 提交事务
      await queryRunner.commitTransaction();
      return true;
    } catch (error) {
      // 回滚事务
      await queryRunner.rollbackTransaction();
      ToolsService.fail(error);
    } finally {
      // 关闭查询运行器
      await queryRunner.release();
    }
  }

  async findAll(
    tagname: string,
    pagination: PaginationDto,
    userId: string,
    needEssays?: number,
  ) {
    try {
      let cacheKey = `TagService_findAll_${tagname}_${pagination.currentPage}_${pagination.pageSize}_${userId}`;
      // 获取缓存
      const cacheData = await this.cacheManager.get(cacheKey);
      if (cacheData) {
        console.log(`${cacheKey}有缓存`);
        return cacheData;
      } else {
        console.log(`${cacheKey}没有缓存`);
        // 添加缓存

        const $tagsRepository = await this.tagsRepository.createQueryBuilder(
          'tag',
        );
        $tagsRepository
          .where('tag.tagname LIKE :param')
          .setParameters({
            param: '%' + tagname + '%',
          })
          .skip(pagination.currentPage * pagination.pageSize)
          .take(pagination.pageSize)
          .leftJoin('tag.user', 'user')
          .andWhere('user.id = :id', { id: userId })
          .orderBy('tag.sortOrder', 'ASC'); //DESC ASC
        /**
         * 是否需要关联查询短文
         */
        if (needEssays == 1) {
          $tagsRepository.leftJoinAndSelect('tag.essays', 'essays');
        }

        let res = await $tagsRepository.getManyAndCount();

        // 添加缓存
        await this.cacheManager.set(cacheKey, res, 1000 * 60 * 60);

        return res;
      }
    } catch (error) {
      ToolsService.fail(error);
    }
  }

  async findOne(id: number): Promise<TagEntity[]> {
    const query = await this.dataSource.query(
      // 执行 SQL 查询
      `SELECT * FROM tag  WHERE id = ?`,
      [id],
    );

    // 将查询结果映射为实体类
    return query.map((result) => new TagEntity(result));
  }

  async update(id: string, updateTagDto: UpdateTagDto) {
    const queryRunner = this.dataSource.createQueryRunner();
    try {
      // 清除整个缓存
      await this.cacheManager.reset();
      const manager = await queryRunner.manager; //使用事务
      const tag = new TagEntity();
      tag.id = id;
      tag.tagname = updateTagDto.tagname;
      tag.sortOrder = updateTagDto.sortOrder;
      await manager.save(tag);
      return tag;
    } catch (error) {
      ToolsService.fail(error);
    } finally {
      await queryRunner.release();
    }
  }

  async remove(id: string) {
    try {
      // 清除整个缓存
      await this.cacheManager.reset();
      await this.tagsRepository
        .createQueryBuilder()
        .delete()
        .from(TagEntity)
        .where('id = :id', { id: id })
        .execute();
    } catch (error) {
      ToolsService.fail(error);
    }
  }
}
